home *** CD-ROM | disk | FTP | other *** search
- ***********************************************
- * A beginners guide to programming *
- * the Win32 SDK. *
- * By Stephen Haunts *
- * *
- * PART 1 *
- * T H E B A R E B O N E S *
- ***********************************************
-
- This document serves as a basic introduction to Win32 programming. If your
- interested in games delevopment with DirectX then you will probable write
- your programs in a different style to what is explained here for the purposes
- of speed. But even so, you still need to know the basics. Before you can
- get a good grasp of windows programming with the Win32 it is recommended
- that you have a fairly strong understanding of writting DOS applications
- in C and/or C++.
-
- Although this document covers the bare bones of Win32 programming it is quite
- a heavy read if your not familiar with this system. It may take a while to
- get a good grasp of the underlying system behind Win32. The method of programming
- is quite different to that of DOS based programming in C. The bit that throws
- most people is the idea of message maps ect.
-
- The some people that the Win32 ways look quite alien and un C like sometimes.
- But don't worry. If I can learn Win32 then you can.
-
- This document builds up a simple windows style hello world program to illustrate
- the basic concepts to Win32 programming (The source code for this programm will
- be bolted on at the end).
-
- I will not cover menus and other resources in this document because I dont
- want to confuse the issue. You have to get a grasp of the basics first.
- Resources and possiby DirectX will come in different documents. Hell I may
- even make a series of programming articals relating to different aspects
- of windows development. What do you think?
-
- If you have any constructive comments about this document (spelling mistakes
- aswell) then please mail me at the following address:
- S.B.B.Haunts@herts.ac.uk
-
- PLEASE NO FLAMING. I GET QUITE NASTY IF PEOPLE FLAME ME FOR SOME STUPID
- PETTY REASON WITHOUT GIVING A FULL EXPLAINATION.
-
- Why Did I Write This Document ?
- -------------------------------
-
- Good question. I my self am personnaly learning to program in windows. I feel
- the best way to get complicated issues to stick in my head are to write short
- notes on them. Because I havn't really found any decent resources on the net
- for beginners in Win32 I decided to write up my notes and publish them for you
- all to view/download/print for free. Arn't I nice :-)
-
- Who The Hell Am I ?
- -------------------
-
- My name is Stephen Haunts and I am 20 years old. I am currently studying for
- a BSc Hons Degree in Computer Science at the University of hertfordshire. I
- have just completed my 2nd year of studies and am about to start my 1 years
- industry placement, for whome I will be working for Argonaut Software (those
- of Star Wing fame on the Super Nintendo console).
-
- I have always been a DOS programmer on the PC but my job requires me to train
- up in Windows programming and DirectX.
-
- OK Here we go folks, have fun :-)
-
- Intoduction to windows programming 'WinHello'
- ---------------------------------------------
-
- Traditionally the introductory program has always been a hello world message.
- Under dos such a program could be written in only a few lines but under
- windows you are looking at more like a 100 lines of code 'OUCH.' Thats even
- worse than a hello world program in assembler :-).
-
- When you are working on a large project though the total size of you windows
- program may actually end up being less than that of a DOS program (lines of
- code that is).
-
- The WinMain Procedure
- ---------------------
-
- Just as every do DOS C program has a procedure called main at its heart, every
- windows program has a similar entry point with the title WinMain (and, yes,
- this title is case sensative). Also, just as a DOS C program may include
- provisions within the main procedure declaration to retrieve command-line
- parameters, the WinMain declaration includes a similar provision in the
- lpszCmdParam parameter, even though command-line parameters are rarely used
- under windows.
-
- However, unlike in DOS programming, the declarations used for WinMain are
- not optional and must be declared exactly in the order and form shown,
- regardless of whether each specific argument will be used or ingored.
-
- Also note that the reserved word PASCAL is used in al exported function declarations,
- indicating to the compiler that Pascal rather than C ordering is used for
- all arguments(values) pused onto the stack. While C commonly uses inverted
- ordering, placing the least-significant bytes first on the stack, windows
- ises pascal ordering which, like Unix, places the most-significant bytes
- first.
-
- Here is the declaration used for WinMain:
-
- int PASCAL WinMain ( HANDLE hInstance,
- HANDLE hPrevInstance,
- LPSTR lpszCmdParam,
- int nCmdShow )
-
- Of the four calling arguments, the first two are of primary importance.
- The data type HANDLE refers to a 32-bit, unsigned value; the hInstance and
- hPrevInstance are unique identifiers supplied by windowsNT and 95 systems.
-
- Inlike DOS applications where where only one program (TSRs excepted) is active
- at a time, multitasking systems require unique identification, not only for
- each application, but also for each instance of an application of an application
- that may be executing. Ergo, the hInstance and hPrevInstance parameters are
- assigned only when an application instance becomes active. they provide
- equivalents of the "task ID" and "process ID" values common in other
- multitasking environments.
-
- The hPrevInstance (previous instance) identifier is the hInstance identifier
- previously assigned to the most recent instance of an application that is
- already excuting. If there is no previous instance of the application
- currrently running, which is frequently the case, this argument will by
- null(0). The reason for this second process identifier will be demonstrated
- presently.
-
- The third prameter, lpszCmdParam, is a long (FAR) pointer to a null-terminated
- (ASCIIZ) string containing any command-line parameters passed to the program
- instance.
-
- The fourth calling parameter, nCmdShow, is simply an integer argument indicating
- whether the newly launched application will be displayed as a normal window
- or initially displayed as an icon.
-
- Next, following the procedure declaration itself, a brief list of local
- variable declarations appears.
-
- {
- static char szAppName[] = "WinHello";
- HWND hwnd;
- MSG msg;
- WNDCLASS wc;
-
- The data types used in the declaration will be covered in more detail later
- in the document. Here is a quike rundown:
-
- * HWND identifies a window handle
-
- * MSG identifies a message value
-
- * WNDCLASS refers to a recford structure used to pass a number of
- values relevant to the application's main window.
-
-
- Registering a Window Class
- --------------------------
-
- The first task accomplished within the WinMain procedure depends on the
- hPrecInstance argument passed. If a previous instance of this application is
- already active, there's no need to register the window class a second time.
- But it's more likely, of course, that this is the first instance of the app-
- lication (hPrevinstance is null) and, therefore, the window class definitions
- must be assigned and the window class registered.
-
- The wc srtructure is defined in Windows.H (which must be included in all
- windows applications). Of the WNDCLASS record fields, the second of the
- fields can usually remain unchanged from one application to another
-
- The first field is the window-style specification. In this example, it is
- assigned two style flag values combined by ORing bitwise. These flags are
- defined in windows.h as 16-bit constants and shall be explained later.
-
- Here the CS_HREDRAW and CS_VREDRAW flags indicate that the following windows
- should be redrawn completely anytime the horizontal or vertical size changes.
- Thus, for the WinHello demo, if the window size changes, the window display
- is completely redrawn, with the hello message string recentered in the new
- display.
-
- if (! hPrevInstance )
- {
- wc.style = CS_HREDRAW | CS_VREDRAW;
- cs.lpfnWndProc = WndProc;
-
- The second field in the WNDCLASS structure, lpfnWndProc, is a pointer to the
- exported procedure WndProc, in this example - which will handle all windows
- messages for this application. The type prefix lpfn identifies this field
- as a "long pointer to function." But realize that these prefic conventions
- are provided for the beifit of the programmer. Tey are not absaolutes, nor do
- these designations place any contraints on the compiler.
-
- The next two record fields are integers, which are resereved to specify extra
- information about the class or window styles. Commonly, neither is required
- and, by default, both are initialized as zeros (0). Incidentally, the
- cb_ prefix stands for count of bytes.
-
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
-
- The next field, hInstance, is simply the recipient of the hInstance argument
- passed by windows when the program is initially called. This is also one field
- assignment that can be considered constant for all applications.
-
- The next three data fields currently assign default values for the
- application's icon, cursor, and background color and pattern.
-
- wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
- wc.hCursor = LoadCursor( Null, IDC_ARROW );
- wc.hbrBackground = GetStockObject( WHITE_BRUSH );
-
- The default IDI_APPLICATION specification for the icon assigns the pre-
- defined image of a white square with a black border. The IDC_ARROW cursor
- assigns the stock cursor graphic of a slanted arrow.
-
- In the third asignment, the hbrBackground field contains the background
- colour and pattern used for the application's client region. The hbr stands
- for handle to brush, where "brush" refers to a pixel patterm used to fill or
- paint an area.
-
- Next, since this application does not have a menu assigned, the menu name is
- entered as a null value. The class name (lpszClassName) is assigned the null-
- terminated (ASCIIZ) string defined previously.
-
- wc.lpszMenuName = NULL;
- wc.lpszClassName = szAppName;
- RegisterClass( &wc );
- }
-
- And last within this conditional subprocess, the RegisterClass function is
- called with the wc structure passed as a paramater (by address) to register
- this window class definition with the NT/95 operating system.
-
- Creating an Application Window
- ------------------------------
-
- While the previous step, registering a window class, has defined char-
- acteristics that are common to all instances of the application, this is not
- yet created the application window itself. Instead, unlike the RegisterClass
- function call, which is called only once, every instance of the application
- must call the CreateWindow function to produce the actual window display.
-
- The handle to the application window that is returned by the CreateWindow
- function will be used later as an argument in other function calls as a
- unique itentifier for the actual window belonging to the application instance.
- But, while many properties of the application class have already been defined,
- other properties have already been defined, other properties specific to this
- instance of the application have not; they are passed now as parameters to
- the CreateWindow function.
-
- hWnd = CreateWindow(
- szAppName, // window class name
- "Hello, World - NT Style", // window caption
- WS_OVERLAPPEDWINDOW, // window style
- CW_USERDEFAULT, // initial X position
- CW_USERDEFAULT, // initial Y position
- CW_USERDEFAULT, // initial X size
- CW_USERDEFAULT, // initial Y size
-
- The first two parameters passed are the application class name - the same
- ASCIIZ string that was used when the class was registered - and the app-
- lication's initial window aption. If you don't want a caption, then pass
- this as null.
-
- The third parameter defines the window style, generically, is passed as
- WS_OVERlAPPEDWINDOW, a value that is a combination of individual flags
- defined in windows.h.
-
- The fourth through seventh parameter established the applicaiton window's
- initial position and size. They can be passed as explicit values or, more
- often, as CW_USERDEFAULT. This parameter instructs windows to use the
- default values for an overlapped window, positioning each successive
- overlapped window at a stepped horizontal and vertical offset from the upper-
- left corner of the screen.
-
- The next parameter is passed as null for the simple reason that this application
- is not associated with a parent window. Alternatively, if this window were to
- be called as a shild process belonging to another aplication, the parent's
- window hadle would be passed as a parameter here.
-
- NULL, // parent window handle
- NULL, // window menu handle
-
- The ninth parameter using in calling the CreateWindow function is also passed
- as null, directing the appliation to use the default system menu. Note,
- however that the menu in question is the windows fram's pull-down menu (upper
- -left icon on most window frames), not the menu (or toolbar), which is defined
- as an application resource and assigned during application class registration.
-
- The tenth calling parameter, which can never be passed as null, is the same
- instance handle originally supplied by the NT/95 system.
-
- hInstance, // program instance handle
- NULL ); // creation parameters
-
- The final parameter, again null in this example, may in other cases provide
- a pointer to additional data for use either by the application window or by
- some subsequent process. In most examples, however, this will be an empty
- (null) argument.
-
- Now, after CreateWindow has been called, the application window has been
- created internally in NT/95 "world view" but does not yet appear on the
- actual screen display. Therefore, the next step is to call the ShowWindow
- function, passing as parameters the hwnd value returned by CreateWindow and
- the nCmdShow argument supplied when Winmain was initially called.
-
- ShowWindow( hwnd, nCmdShow );
- UpdateWindow( hwnd );
-
- The ShowWindow function, however, contrary to what you might assume, does only
- a portion of the task of creating (painting) the window display. It is
- principally responsible for creating the window frame, caption bar, menu
- bar, and minimize/maximize buttons. But what this function does not create
- is the client window area -the display area specific to the application
- itself. Therefore, one more function call is necessary before the window
- display is complete: a call to the UpdateWindow function with the hwnd window
- handle as an argument (which actually posts a WM_PAINT message to the
- application instructing it to repaint its own window area- a process that
- will be discussed in a moment.
-
- The Message-Handling Loop
- -------------------------
-
- Windows creates and manages a seperate message queue for each active windows
- program instance. Thus, when and keyboard or mouse event occurs, windows
- translates this event into a message value. This value is placed in the
- application's message queue. where it waits until it is retrieved by the
- applicationsinstance, which is precisely the purpose of the message-handling
- loop.
-
- The message handling loop begins by calling the GetMessage function to retrieve
- messages from the application instance's message queue. As long as the message
- retrieved is not a WM_QUIT message (0x0012), GetMessage will return a TRUE
- (nonzero) result. The actual message value is returned in the msg structure
- which was passed by address.
-
- while( GetMessage( &msg, NULL, 0, 0) )
- {
-
- The syntax for the GetMessage function is defined as:
-
- BOOL GetMessage( lpMsg, HWND, wMsgFilterMin, wMsgFilterMax )
-
- In most cases, only the first parameter is actually used (to return the
- message itself). The remaining three parameters are usually passed as null
- or zero.
-
- The initial parameter is a pointer to a message structure to receive the
- message information retrieved and, subsequently, to pass this data on though
- to the TranslateMessage and DispatchMessage functions. And, obviously, without
- this parameter, there would be little point in calling the GetMessage function
- at all.
-
- The third and fourth parameters provide filter capabilities, restricting the
- message types returned. When both parameters are passed as 0, no filtering
- occurs. Alternatively, constants such as WM_KEYFIRST and WM_KEYLASY could be
- passed as filter values to restrict message retrieval to keyboard events or,
- by using WM_MOUSEFIRST and WM_MOUSELAST, to retrieve only mouse-related
- messages.
-
- filters and window selection aside, however, the GetMessage function (together
- with the PeekMessage and WaitMessage functions) has another important char-
- acteristic.
-
- Conventionally, loop statements monopolize the system until terminated, thus
- preempting or preventing other operations for the duration of the loop. And,
- in other circumstances -remember this as a caution -even under windows, loop
- operations can tie up system resources.
-
- The GetMessage function, however, has the ability to preemp the loop operation
- to yield control to other applications when no messages are available for the
- current application, or when WM_PAINT or WM_TIMER messages directed to other
- tasks are available. Thus, it can give other applications their share of CPU
- time to execute.
-
- For the present, when the aplication recieved an event messsage (other than
- WM_QUIT), the message value is passed. First, it goes to the windows Translate-
- Message function for and keystroke translation that may be specific to the
- application. Then it is passed to the DispatchMessage handler, where the message
- information is passed to the next appropriate message-handling procedure (back
- to windows, either for immediate handling or, indirectly, for forwarding to the
- exported WndProc procedure).
-
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
-
- Finally, when the message-processing loop terminates, the wParam argument from
- the final message retrieved is, in turn, returned to the calling application
- -the NT/95 desktop itself.
-
- return msg.wParam;
- }
-
- Messages and Event-Driven Programming
- -------------------------------------
-
- In its simplest form, message driven programming (also known as event driven
- programming) is a process by which various subprocesses and/ or applications
- communicate. In windows, messages are the process used by windows itself to
- manage a multitasking system and to share keyboard, mouse, and other
- resources by distributing information to applications, application instances,
- and processes within an application.
-
- Thus, under windows, instead of applications recieving information directly
- from the keyboard or the mouse driver, the NT/95 operating system intercepts
- all input information, packaging this information using the MSG message
- structure and then forwarding the prepared messages to the appropriate recipients.
- In turn, the recipient aplications use TranslateMessage for application-specific
- interpretation (particularly accelerator key assignments) before calling
- DispatchMessage to forward individual traffic items to their appropriate handlers.
-
- Furthor more, the process descipbed is not limited to keyboard and mouse events.
- Instead, this includes all input devices (including ports), as well as messages
- generated by application and child subprocesses, windows timers, or, quite
- frequently by windows itself.
-
- Abstract descriptions, however, provide only a theoretical outline without
- really illustrating how these processes function.
-
- The Message Record Structure
- ----------------------------
-
- The MSG (message structure) record type is defined in WinUser.h as
-
- typedef struct tagMSG
- {
- HWND hwnd;
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
- DWORD time;
- POINT pt;
- } MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
-
- The POINT data type is defined in WinDef.h as:
-
- typedef struct tagPOINT
- {
- int x;
- int y;
- } POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
-
- The message-event fields are used as:
-
- - hWnd: The handler of the specific window to which the message is directed.
- Please note that each application is itself composed of a series of
- seperate windows. These windows include the frame, the caption bar,
- the system menu, and minimize and maximize buttome, as well as the
- application's main display window. Normally, only messages directed
- to the client window will be forwarded, by the DispatchMessage proc',
- to the application's WndProc procedure. Messages directed to other
- application windows are generally handled indirectly by NT/95, even
- though this may result, in turn, in further messages being sent to
- the client window.
-
- - message: A 16bit value identifying the message. Constants corresponding to
- all message values are provided though windows.h and begin with the
- WM_ prefix (which stands for windows message). For example, a mouse
- button event message might be identified by the constant WM_LBUTTON.
-
- - wParam: A 32bit (double word) message parameter. The value format and meaning
- depend on the primary event message type. Variously, the wParam
- argument might convey a coordinate point pair, use the low word value
- to identify a secondary message type, provde some other type of data, of
- be ignored entirely. In many cases, the wParam value will be treated as
- two seperate word values with different functions.
-
- - lParam: A 32bit (long) message parameter. The value and meaning of this parameter
- depend on the primary event message type. Variously, the lParam argument
- might provide a pointer to a string or record structure; break down as a
- group of word, byte, or flag values; or, quite frequently, be completely
- unused.
-
- - time: The double word time value identifies the time the message was placed in the
- message queue.
-
- - pt: This field contains the mouse coordinates at the time the message was
- placed in the message queue (irrespective of the message-event type
- or origin).
-
- Note that these last two fields are not passed to the WndProc procedure.
- Instead, these two fields are used only by NT/95, principally to resolve any
- conflict over the order of events and, of course, to determine where a specific
- event should be addressed.
-
- The WndProc Procedure
- ---------------------
-
- The WndProc procedure is the point where each application actually begins to function.
- Remember, the WndProc procedure recieves messages indirectly from the NT/95 operating
- system, but the WndProc procedure determines the application's response to the
- messages received.
-
- Previously, when the application window class was registered, the address of
- the WndProc subroutine wassed to windows as:
-
- wc.lpfnWndProc = WndProc;
-
- And, given this address, windows calls WndProc directly, passing event messages
- in the form of four parameters, as:
-
- long FAR PASCAL WndProc( HWND hwnd,
- UINT msg,
- UINT wParam,
- LONG lPARAM )
-
- The four calling parameters received correspond to the first four fields of the
- message structure described above, beginning with the hwnd parameter.
- identifying the window to which the message is directed. Since most applications
- have only one client window that will be addressed thus, this parameter may
- seem superfuous. This parameter will, however, frequently be needed as an
- argument for use by other processes.
-
- At the present, it's the second calling parameter, msg, that is immediately
- crucial and identifies the window event message. The third and fourth parameters,
- wParam and lParam, provide amplifying information to accompany the window
- event message.
-
- Typically, the WndProc procedure does relatively little or nothing itself
- outside the switch...case responding to the msg parameter. In the hello program
- demo, local response is provided for only two event messages: the WM_PAINT
- and WM_DESTROY messages. All other event messages handled are by default
- (by the NT/95 operating systems).
-
- The first of these two, WM_PAINT, is a message that is generally not issued
- directly. It will be issued indirectly anytime an application window is
- created, moved, resized, restored from an icon, uncovered by a change in some
- other application window, or something else has occured -in this or in some
- other application- to invalidate the client area of the present application.
-
- The DOS equivalent of the Hello program would consist principally of a print
- statement, possibly with an optional clear screen statement. For the windows
- version, however, there are differences for two main reasons:
-
- * Because the response to the WM_PAINT message is not a one-time
- occurance.
-
- * Because a bit more is accomplished than simply dumping the text
- to the screen.
-
- The first requirement, before anything can be written to the client window, is
- for the application to retrieve a handle (hdc) to the device context (the output
- device or, in this example, the screen). After the screen update is finished,
- this handle will be released by calling the endpaint function.
-
- switch( msg )
- {
- case WM_PAINT:
- hdc = BeginPaint( hwnd, &ps );
- GetClientRect( hwnd, &rect );
-
- After retrieving the device context handle, the GetClientRect procedure is called
- to retrieve the rect structure with coordinates describing the client window.
- The rect structure consists of four fields, which report coordinates for the client
- window. However, the coordinates reported are relative to the client window
- itself. Therefore, the left and top fields are returned as zeros, and the right
- and bottom fields return the current width and hight of the client window
- (reported in pixels).
-
- Once the window coordinates have been retreived, the rect structure can be used
- as an argument in the next step to specify the region where the actual message
- will be drawn.
-
- DrawText( hdc, "Hello World", -1, &rect,
- DT_SINGLELINE | DT_CENTRE | DT_VCENTER );
-
- Since print statements, per se, cannot be used in windows (because they are
- unsuited for a graphics display environment), the DrawText function is used
- instead. DrawText begins with the hdc argument providing access to the active
- display, followed by the string (text) to be drawn.
-
- The third parameter, -1, indicates that the string argument is a null-terminated
- string. Alternatively, this parameter could be a value specifying the string
- length, with the second parameter an indirect reference to a character array.
-
- The fourth argument is the address of the rect structure, identifying an area
- where the string will be drawn. The fifth argument is a combination of flags
- that set alignment and ristrict the text drawn to a single display line.
-
- Last, the EndPaint function is called, again with the client window handle and
- the paint structure (ps) as argument. This function releases the device context
- and validates the now-restored client area, and incidentally, completes the
- response to the WM_PAINT message.
-
- EndPaint( hwnd, &ps );
- return( 0 );
-
- The second application message requiring a local resonse is the WM_DESTROY
- message, which is issued when the application is ready to close. This message
- can be generated via several channels. For this example though it is issued
- only if/when the system menu close option is selected.
-
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
-
- The WM_DESTROY message is issued to give the application an opportunity to do
- any necessary cleanup before shutting down. Therefore, as circumstances demand
- the application response at this point could include provisions for calling a
- dialog box to requiest confirmation, for closing/saving files, or for any other
- final tasks required for a smooth exit.
-
- Finally (unless, of course, termination is to be aborted), the WN_DESTROY
- response is completed by calling the PostQuitMessage function, which in turn,
- places a WM_QUIT message in the application's message queue to terminate the
- message loop in WinMain.
-
- Explicit handling has been provided for only two of the messages that might be
- sent to this application. Provisions are also required to return to windows
- for procesing all mssages that have not been explicitly handled here, as a
- default case.
-
- default: // is msg unprocessed
- return( // return to windows
- DefWindowProc( hwnd, msg, wParam, lParam ) );
- }
- return( NULL );
- }
-
- This default provision returns the message -precisely as it was originally
- received- to windows, then also returns the results from DefWindowProc to the
- windows calling process. This final provision should be considered standard
- for all WndPoc message-handler procedures.
-
- For a windows program the .C source code is only a part of the story. In most
- cases, the application will also incorporate an .H header file and, almost
- always, a .RES resource file.
-
- Here is the complete source code for the hello world program. You can just
- cut out the program from this document and compile it straght off. The code
- should work under any windows compiler with the Win32 libraries. I have only
- tested the code so far under Microsoft Visual C v4.
-
- 8<-----------------Cut-out-this-code-and-compile-it--------------------------
-
- //===================================//
- // Hello.C //
- // HELLO WORLD //
- //===================================//
-
- #include <windows.h>
-
- long APIENTRY WndProc( HWND hwnd, UINT msg,
- UINT wParam, LONG lParam )
- {
- HDC hdc;
- PAINTSTRUCT ps;
- RECT rect;
-
- switch( msg )
- {
- case WM_PAINT:
- hdc = BeginPaint( hwnd, &ps );
- GetClientRect( hwnd, &rect );
- DrawText( hdc, "Hello, World! Muddy Funsters", -1, &rect,
- DT_SINGLELINE | DT_CENTER | DT_VCENTER );
- EndPaint( hwnd, &ps );
- return( 0 );
-
- case WM_DESTROY: // message: window being destroyed
- PostQuitMessage(0);
- break;
-
- default: // if msg unproccessed,
- // return to Windows
- return( DefWindowProc( hwnd, msg, wParam, lParam ) );
- }
- return TRUE;
- }
-
- int APIENTRY WinMain( HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdParam, int nCmdShow )
- {
- static char szAppName[] = "WinHello";
- HWND hwnd;
- MSG msg;
- WNDCLASS wc;
-
- if( ! hPrevInstance )
- {
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
- wc.hCursor = LoadCursor( NULL, IDC_ARROW );
- wc.hbrBackground = GetStockObject( WHITE_BRUSH );
- wc.lpszMenuName = NULL;
- wc.lpszClassName = szAppName;
- RegisterClass( &wc );
- }
- hwnd = CreateWindow(
- szAppName, // window class name
- "Muddy Funster Software", // window caption
- WS_OVERLAPPEDWINDOW, // window style
- 100, // initial X position
- 100, // initial Y position
- 400, // initial X size
- 200, // initial Y size
- NULL, // parent window handle
- NULL, // window menu handle
- hInstance, // program instance handle
- NULL ); // creation parameters
- ShowWindow( hwnd, nCmdShow );
- UpdateWindow( hwnd );
-
-
- while( GetMessage( &msg, NULL, 0, 0 ) )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
- return msg.wParam;
- }
-
- 8<--------------------------------------------------------------------------
-
- Windows Conventions and Data Types
- ----------------------------------
-
- This following section describes some windows NT/95 conventions for naming,
- as well as some of the windows data types, data structures, and handle
- identifiers.
-
- Variable Names and Hungarian Notation
- -------------------------------------
-
- As programs have become more complex in terms both of size and of the proliferation
- of data types, many programmers have adopted a variable-naming convention, which is
- commonly fered to as Hungarian notation (named in honor of Microsoft programmer,
- Charles Simonyi).
-
- Using Hungarian notation, variable names begin with one or more lowercase
- letters, which denote the variable type, thus providing an inherent identification.
- For example, the prefix h is used to identify a handle, as in hWnd or hDlg,
- refering to a window and dialog handles, respectively. In like fasion, the
- prefix lpsz identifies a long pointer to a null-terminated (ASCIIZ) string.
-
- The followng table summarizes the Hungarian notation conventions. These aren't
- cast in stone though, you can come up with variations.
-
- ----------------------------------------------------
- | PREFIX | DATA TYPE |
- |-----------+--------------------------------------|
- | d | boolean |
- | by | byte or unsigned char |
- | c | char |
- | cx/cy | short used as size |
- | dw | DWORD, double word or unsigned long |
- | fn | function |
- | h | handle |
- | i | int |
- | l | long |
- | n | short int |
- | s | string |
- | sz | ASCIIZ null-terminated string |
- | w | WORD unsigned int |
- | x,y | short used as coordinates |
- |--------------------------------------------------|
-
- Predefined Constants
- --------------------
-
- Windows also uses an exclusive list of predefined constants, which are used as
- messages, flag values, and other operational parameters. These constants
- values are always uppercase, and most include a two or three letter prefix set
- off by an underscore. Here are some examples.
-
- CS_HREDRAW CS_VREDRAW CW_USERDEFAULT
-
- DT_CENTER DT_SINGLELINE DT_VCENTER
-
- IDC_ARROW IDI_APPLICATION WM_DESTROY
-
- WM_PAINT WS_OVERLAPPEDWINDOW
-
- In the case of constant identifiers, the prefixes indicate the general category
- or the constant. The table below shows the meaning of the prefixes.
-
- ----------------------------------------------------
- | PREFIX | CATEGORY |
- |-----------+--------------------------------------|
- | CS | Class style |
- | CW | Create window |
- | DT | Draw text |
- | IDC | Cursor ID |
- | IDI | Icon ID |
- | WM | Window message |
- | WS | Window style |
- ----------------------------------------------------
-
- Data Types
- ----------
-
- Windows also uses a wide variety of new data types and type identifiers, most
- of which are defined in either the WinDef.h or WinUser.H header files.
-
- ------------------------------------------------------
- | DATA TYPE | MEANING |
- |-----------+----------------------------------------|
- | FAR | Same as far |
- | PASCAL | Same as pascal |
- | WORD | Unsigned integer (16 bits) |
- | UINT | unsigned integer, same as word |
- | DWORD | double word, unsigned long int (32bits)|
- | LONG | signed long pointer to character string|
- | LPSTR | long (far) pointer to character string |
- ------------------------------------------------------
-
- Data Structures
- ---------------
-
- Similarly, windows adds a variety of new data structures. Again, most are
- defined in either WinDef.h or WinUser.h.
-
- ---------------------------------------------------------------
- | STRUCTURE | EXAMPLE | MEANING |
- |--------------+---------+------------------------------------|
- | MSG | msg | Message structure |
- | PAINTSTRUCT | ps | Paint structure |
- | PT | pt | Point structure (mouse position) |
- | RECT | rect | Rectangle struc',2 coordinate pairs|
- | WNDCLASS | wc | Window class structure |
- ---------------------------------------------------------------
-
-
- Handle Identifiers
- ------------------
-
- In like fasion, a variety of handles are defined for use with different
- windows elements. Like constants, the handle types use all uppercase. The
- following table shows a few examples.
-
- ----------------------------------------------------------------
- | HANDLE TYPE | EXAMPLES | MEANING |
- |--------------+-------------+---------------------------------|
- | HANDLE |hnd or hdl | Generic handle |
- | HWND |hwnd or hWnd | Window handle |
- | HDC |hdc or hDC | Device context handle (CRT) |
- | HBRUSH |hbr or hBrush| Paint brush handle |
- | HPEN |hpen or hPen | Drawing pen handle |
- ----------------------------------------------------------------
-
-